import { getProductInfosByIds } from '@/api/giga';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from '@/components/dropdown-menu';
import Funnel from '@/components/Funnel';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
  Sidebar,
  SidebarContent,
  SidebarHeader,
  SidebarMenu,
  SidebarMenuAction,
  SidebarMenuItem,
  SidebarProvider,
  SidebarTrigger,
} from '@/components/ui/sidebar';
import config, { CollectState } from '@/config';
import { Task, TaskInfo, TaskType } from '@/entrypoints/hook/useConcurrentRequest';
import { useDirectoryHandle } from '@/entrypoints/hook/useDirectoryHandle';
import { getProductState, importFile, State } from '@/lib/filesystem';
import { getGigaSkuAndProductId } from '@/lib/giga';
import { cn, getAllFDirectoryHandleByDirectoryHandle, saveTextFile } from '@/lib/utils';
import { useVirtualizer } from '@tanstack/react-virtual';
import {
  ArrowBigDown,
  ArrowBigDownDash,
  Inbox,
  MoreHorizontal,
  RefreshCcw,
  Search,
  Trash2,
} from 'lucide-react';
import { MutableRefObject } from 'react';
import { toast } from 'sonner';
import { CollectGigaProduct } from './App';
import { useGiga } from './hook/useGiga';

enum OrderDirection {
  'asc' = '升序',
  'desc' = '降序',
}

interface OrderOptions {
  skuInfo: string;
}
function order(productCollectInfos: ProductCollectInfo[], orderOptions: OrderOptions) {
  // 获取排序方向，默认为升序
  const isDescending = orderOptions.skuInfo === OrderDirection.desc;

  // 复制数组以避免修改原数组（根据需求决定是否需要）
  const sortedArray = [...productCollectInfos];

  sortedArray.sort((a, b) => {
    // 比较skuInfo字符串
    const comparison = a.skuInfo.localeCompare(b.skuInfo);
    // 根据排序方向调整结果
    return isDescending ? -comparison : comparison;
  });

  return sortedArray;
}

type Props = {
  children?: React.ReactNode;
  className?: string;
  runTaskItems: (
    collectInfoList: TaskInfo[],
    collectGigaProduct: CollectGigaProduct,
    enqueueTask: (task: Task['task']) => Promise<unknown>,
  ) => Promise<unknown[]>;
  enqueueTask: (task: Task['task']) => Promise<unknown>;
  totalTask: MutableRefObject<Task[]>;
  completedTask: MutableRefObject<Task[]>;
};

export interface ProductCollectInfo {
  skuInfo: string;
  state: State;
  selected?: boolean;
}

export default function LocalDiskInfo({
  children,
  className,
  runTaskItems,
  enqueueTask,
  totalTask,
  completedTask,
  ...props
}: Props) {
  const { getDirectoryHandle } = useDirectoryHandle();
  const [productCollectInfos, setProductCollectInfos] = useState<ProductCollectInfo[]>([]);
  const virtualizerParentRef = useRef(null);
  const appCofing = useAppConfig();
  const { collectGigaProduct } = useGiga();
  const [isfreshing, setIsfreshing] = useState(false);
  const [searchValue, setSearchValue] = useState('');
  const searchRef = useRef<HTMLInputElement>(null);
  const [isSelectedAll, setIsSelectedAll] = useState(false);
  const [collectStateList, setCollectStateList] = useState<CollectState[]>([
    CollectState.init,
    CollectState.success,
    CollectState.error,
  ]);
  // 是否包含已选择
  const [filterSeleted, setFilterSelected] = useState(false);
  const rootDirectoryName = useRef('');
  const appConfig = useAppConfig();

  const rowVirtualizer = useVirtualizer({
    count: productCollectInfos.length,
    getScrollElement: () => virtualizerParentRef.current,
    estimateSize: (i) => 32,
    overscan: 5,
  });

  const getSkuInfos = useCallback(
    async function getSkuInfos() {
      const directoryHandle = await getDirectoryHandle();
      rootDirectoryName.current = directoryHandle.name;
      // 获取所有的货号目录
      const skuInfoDirectoryHandles =
        await getAllFDirectoryHandleByDirectoryHandle(directoryHandle);

      let newProductCollectInfos: ProductCollectInfo[] = [];
      await Promise.all(
        skuInfoDirectoryHandles.map(async (skuInfoDirectoryHandle) => {
          const state = await getProductState(
            appCofing.productStateFilename,
            skuInfoDirectoryHandle,
          );

          newProductCollectInfos.push({
            skuInfo: skuInfoDirectoryHandle.name,
            state: state,
          });
        }),
      );

      // 搜索词过滤
      if (searchValue) {
        newProductCollectInfos = newProductCollectInfos.filter((newProductCollectInfo) => {
          return newProductCollectInfo.skuInfo.includes(searchValue);
        });
      }

      // 按状态进行过滤
      newProductCollectInfos = newProductCollectInfos.filter((newProductCollectInfo) => {
        return collectStateList.includes(newProductCollectInfo.state.collectState);
      });

      // 进行排序
      newProductCollectInfos = order(newProductCollectInfos, {
        skuInfo: OrderDirection.asc,
      });

      setProductCollectInfos((oldProductCollectInfos) => {
        // 主要是获取之前的属性
        return newProductCollectInfos
          .map((newProductCollectInfo) => {
            const oldProductCollectInfo = oldProductCollectInfos.find((oldProductCollectInfo) => {
              return oldProductCollectInfo.skuInfo === newProductCollectInfo.skuInfo;
            });
            if (oldProductCollectInfo) {
              newProductCollectInfo.selected = oldProductCollectInfo.selected;
            }
            return newProductCollectInfo;
          })
          .filter((newProductCollectInfo) => {
            // 按是否选择进行过滤
            return filterSeleted ? newProductCollectInfo.selected : true;
          });
      });
    },
    [getDirectoryHandle, searchValue, collectStateList, filterSeleted],
  );

  useEffect(() => {
    const timmer = setInterval(getSkuInfos, 3000);
    // 先执行一次
    getSkuInfos();
    return () => {
      clearInterval(timmer);
    };
  }, [getSkuInfos]);

  // 单个的采集和重新采集
  async function collect(productCollectInfo: ProductCollectInfo, force = false) {
    const [gigaSku, gigaProductId] = getGigaSkuAndProductId(productCollectInfo.skuInfo);
    await collectGigaProduct({
      gigaProductId,
      gigaSku,
      skuIdInfo: productCollectInfo.skuInfo,
      force,
      taskType: TaskType.collect,
    });
  }
  // 批量采集和重新采集
  async function batchCollect(force = false) {
    const selectedProductCollectInfos = productCollectInfos.filter((productCollectInfo) => {
      return productCollectInfo.selected;
    });
    const collectInfoList = selectedProductCollectInfos.map((productCollectInfo) => {
      const [gigaSku, gigaProductId] = getGigaSkuAndProductId(productCollectInfo.skuInfo);
      return {
        skuIdInfo: productCollectInfo.skuInfo,
        gigaProductId: gigaProductId,
        gigaSku: gigaSku,
        force: force,
        taskType: TaskType.collect,
      };
    });

    await runTaskItems(collectInfoList, collectGigaProduct, enqueueTask);
    if (totalTask.current.length === completedTask.current.length) {
      toast.success(`完成所有的批量任务`);
    }
  }

  // 删除货号目录
  async function deleteSkuInfo(productCollectInfo: ProductCollectInfo) {
    const directoryHandle = await getDirectoryHandle();
    const skuInfoDirectoryHandles = await directoryHandle.getDirectoryHandle(
      productCollectInfo.skuInfo,
    );
    await skuInfoDirectoryHandles.remove({
      recursive: true,
    });
  }

  // 批量删除货号目录
  async function batchDeleteSkuInfo() {
    const selectedProductCollectInfos = productCollectInfos.filter((productCollectInfo) => {
      return productCollectInfo.selected;
    });
    await Promise.all(
      selectedProductCollectInfos.map(async (productCollectInfo) => {
        await deleteSkuInfo(productCollectInfo);
      }),
    );
  }

  // 搜索货号
  async function searchSkuInfo(event: React.MouseEvent) {
    const value = searchRef.current?.value || '';
    setSearchValue(value);
  }

  // 选择失败货号
  async function selectErrorSkuInfo(event: React.MouseEvent) {
    setProductCollectInfos((oldProductCollectInfos) => {
      return oldProductCollectInfos
        .filter((oldProductCollectInfo) => {
          return oldProductCollectInfo.state.collectState === CollectState.error;
        })
        .map((oldProductCollectInfo) => {
          return {
            ...oldProductCollectInfo,
            selected: true,
          };
        });
    });
    setCollectStateList([CollectState.error]);
  }

  // 导出错误的货号
  async function exportErrorSkuInfo() {
    const errorSkuInfos = productCollectInfos.filter((productCollectInfo) => {
      return productCollectInfo.state.collectState === CollectState.error;
    });
    const text = errorSkuInfos
      .map((errorSkuInfo) => {
        return errorSkuInfo.skuInfo;
      })
      .join('\n');
    const directoryHandle = await getDirectoryHandle();
    await saveTextFile(directoryHandle, text, appConfig.productErrorSkuInfoFilename);
    toast.success(`导出失败的货号成功`);
  }

  // 导入货号,货号以 id 的形式进行导入
  async function importSkuInfo() {
    const text = await importFile();
    if (text) {
      const productIds = text.replaceAll('\r', '').split('\n');
      const productInfos = await getProductInfosByIds(productIds);
      if (productInfos.code === 200 && productInfos.data && productInfos.data.length > 0) {
        const data = productInfos.data;
        const skuIdInfos: string[] = [];
        await Promise.all(
          data.map(async (productInfo) => {
            const skuIdInfo =
              productInfo.product.sku + config.gigaDelimiter + productInfo.product.id;
            // 生成对应的货号目录就可以了
            const directoryHandle = await getDirectoryHandle();
            // 创建对应货号的目录
            await directoryHandle.getDirectoryHandle(skuIdInfo, { create: true });
            skuIdInfos.push(skuIdInfo);
          }),
        );
        await getSkuInfos();
        // 让生成的货号被选择
        setProductCollectInfos((oldProductCollectInfos) => {
          return oldProductCollectInfos.map((oldProductCollectInfo) => {
            return {
              ...oldProductCollectInfo,
              selected: skuIdInfos.includes(oldProductCollectInfo.skuInfo),
            };
          });
        });
      }
    }
  }

  return (
    <SidebarProvider
      className="w-auto relative"
      style={{
        // @ts-ignore
        '--sidebar-width': '23em',
      }}
    >
      <SidebarTrigger
        title="折叠/展开"
        className="absolute transition-[left] left-0 z-50 top-2 !cursor-pointer group-has-[[data-collapsible=offcanvas]]/sidebar-wrapper:left-[-1.6em]"
      ></SidebarTrigger>
      <div className="bd-gray rounded-lg mr-2 overflow-hidden flex">
        <div className={cn(className, 'relative')} {...props}>
          <Sidebar variant="sidebar" className="h-[100%] absolute w-full">
            <SidebarHeader className=" ">
              <div className="ml-5 flex items-center flex-row">
                <div className="text-lg">
                  {rootDirectoryName.current ? rootDirectoryName.current : '目录文件'}
                </div>
                <div className="ml-auto">
                  <RefreshCcw
                    size={14}
                    className="cursor-pointer transition-transform"
                    style={{
                      transform: isfreshing ? 'rotate(90deg)' : 'rotate(0deg)',
                    }}
                    onClick={async () => {
                      if (isfreshing) {
                        return;
                      }
                      setIsfreshing(true);
                      await getSkuInfos().finally(() => {
                        setIsfreshing(false);
                      });
                    }}
                  ></RefreshCcw>
                </div>
              </div>
              <div className="flex items-center">
                <div className="relative max-w-md">
                  <Input
                    ref={searchRef}
                    defaultValue={searchValue}
                    placeholder="货号搜索..."
                    className="w-full rounded-sm bg-background border border-input pr-8"
                  />
                  <Search
                    onClick={searchSkuInfo}
                    className="absolute cursor-pointer right-3 top-1/2 h-4 w-4 -translate-y-1/2 text-gray-400"
                  />
                </div>
                <div className="ml-auto">
                  <DropdownMenu>
                    <DropdownMenuTrigger asChild>
                      <Funnel size={16} className="cursor-pointer"></Funnel>
                    </DropdownMenuTrigger>
                    <DropdownMenuContent
                      side="right"
                      align="start"
                      style={{
                        zIndex: config.dropdownMenuZIndex,
                      }}
                    >
                      <DropdownMenuItem className="cursor-pointer">
                        <div
                          className="flex items-center"
                          onClick={(event) => {
                            event.stopPropagation();
                          }}
                        >
                          <Checkbox
                            checked={filterSeleted}
                            onCheckedChange={(state) => {
                              setFilterSelected(state ? true : false);
                            }}
                            id={`filter-clstools-seleted`}
                            className="rounded-[2px] mr-3"
                          />
                          <Label
                            className="whitespace-nowrap mb-0"
                            htmlFor={`filter-clstools-seleted`}
                          >
                            只包括已经选择的
                          </Label>
                        </div>
                      </DropdownMenuItem>
                      {Object.values(CollectState).map((collectState) => {
                        return (
                          <DropdownMenuItem key={collectState} className="cursor-pointer">
                            <div
                              className="flex items-center"
                              onClick={(event) => {
                                event.stopPropagation();
                              }}
                            >
                              <Checkbox
                                checked={collectStateList.includes(collectState)}
                                onCheckedChange={(state) => {
                                  setCollectStateList((oldCollectStateList) => {
                                    if (state) {
                                      return [...oldCollectStateList, collectState];
                                    } else {
                                      return oldCollectStateList.filter(
                                        (oldCollectState) => oldCollectState !== collectState,
                                      );
                                    }
                                  });
                                }}
                                id={`collect-state-filter-clstools-${collectState}`}
                                className="rounded-[2px] mr-3"
                              />
                              <Label
                                className="whitespace-nowrap mb-0"
                                htmlFor={`collect-state-filter-clstools-${collectState}`}
                              >
                                {collectState}
                              </Label>
                            </div>
                          </DropdownMenuItem>
                        );
                      })}
                    </DropdownMenuContent>
                  </DropdownMenu>
                </div>
              </div>
              <div className="flex items-center">
                <Button onClick={selectErrorSkuInfo} className="mr-3" size={'sm'}>
                  选择失败货号
                </Button>
                <Button onClick={exportErrorSkuInfo} className="" size={'sm'}>
                  导出失败货号
                </Button>
              </div>
              <div className="flex items-center">
                <Button onClick={importSkuInfo} className="" size={'sm'}>
                  导入货号
                </Button>
              </div>
              <div className="flex items-center">
                <div className="flex gap-2 bd-bottom-gray items-center">
                  <Checkbox
                    checked={isSelectedAll}
                    onCheckedChange={(state) => {
                      setIsSelectedAll(state ? true : false);
                      setProductCollectInfos((oldProductCollectInfos) => {
                        return oldProductCollectInfos.map((oldProductCollectInfo) => {
                          return {
                            ...oldProductCollectInfo,
                            selected: state ? true : false,
                          };
                        });
                      });
                    }}
                    id="localDiskinfo-select-info"
                    className="rounded-[2px] mr-2 border-[#478ffc] data-[state=checked]:bg-[#478ffc] data-[state=checked]:text-primary-foreground"
                  />
                  <Label className="whitespace-nowrap mb-0" htmlFor="localDiskinfo-select-info">
                    全选
                  </Label>
                </div>
                <div className="ml-auto">
                  <DropdownMenu>
                    <DropdownMenuTrigger asChild>
                      <MoreHorizontal size={16} className="cursor-pointer"></MoreHorizontal>
                    </DropdownMenuTrigger>
                    <DropdownMenuContent
                      side="right"
                      align="start"
                      style={{
                        zIndex: config.dropdownMenuZIndex,
                      }}
                    >
                      <DropdownMenuItem
                        className="cursor-pointer"
                        onClick={() => {
                          batchCollect();
                        }}
                      >
                        <ArrowBigDown></ArrowBigDown>
                        <span>批量采集</span>
                      </DropdownMenuItem>
                      <DropdownMenuItem
                        className="cursor-pointer"
                        onClick={() => {
                          batchCollect(true);
                        }}
                      >
                        <ArrowBigDownDash></ArrowBigDownDash>
                        <span>批量重新采集</span>
                      </DropdownMenuItem>
                      <DropdownMenuItem
                        className="cursor-pointer text-destructive hover:!text-destructive/90"
                        onClick={() => {
                          batchDeleteSkuInfo();
                        }}
                      >
                        <Trash2></Trash2>
                        <span>批量删除</span>
                      </DropdownMenuItem>
                    </DropdownMenuContent>
                  </DropdownMenu>
                </div>
              </div>
            </SidebarHeader>
            <SidebarContent className="px-4" ref={virtualizerParentRef}>
              <SidebarMenu
                className="gap-0"
                style={{
                  height: `${rowVirtualizer.getTotalSize()}px`,
                  position: 'relative',
                }}
              >
                {rowVirtualizer.getVirtualItems().map((virtualRow, index) => {
                  const productCollectInfo = productCollectInfos[virtualRow.index];
                  return (
                    <SidebarMenuItem
                      className="flex items-center"
                      key={productCollectInfo.skuInfo}
                      style={{
                        height: `${virtualRow.size}px`,
                        transform: `translateY(${virtualRow.start - index * virtualRow.size}px)`,
                      }}
                    >
                      <Checkbox
                        checked={productCollectInfo.selected || false}
                        onCheckedChange={(state) => {
                          setProductCollectInfos((oldProductCollectInfos) => {
                            return oldProductCollectInfos.map((oldProductCollectInfo) => {
                              if (oldProductCollectInfo.skuInfo === productCollectInfo.skuInfo) {
                                return {
                                  ...oldProductCollectInfo,
                                  selected: state ? true : false,
                                };
                              }
                              return oldProductCollectInfo;
                            });
                          });
                        }}
                        className="rounded-[2px] mr-2 border-[#478ffc] data-[state=checked]:bg-[#478ffc] data-[state=checked]:text-primary-foreground"
                      />
                      <div
                        title={
                          productCollectInfo.state.collectState === CollectState.error
                            ? productCollectInfo.state.collectState +
                              `: ${productCollectInfo.state.collectErrorMessage || ''}`
                            : productCollectInfo.state.collectState
                        }
                      >
                        <Inbox
                          size={16}
                          className={`mr-2 shrink-0 ${productCollectInfo.state.collectState === CollectState.error ? 'text-destructive' : productCollectInfo.state.collectState === CollectState.success ? '!text-primary' : ''}`}
                        ></Inbox>
                      </div>
                      <div className="whitespace-nowrap flex items-center">
                        <div className="text-sm select-text">{productCollectInfo.skuInfo}</div>
                      </div>
                      <DropdownMenu>
                        <DropdownMenuTrigger asChild>
                          <SidebarMenuAction>
                            <MoreHorizontal />
                          </SidebarMenuAction>
                        </DropdownMenuTrigger>
                        <DropdownMenuContent
                          side="right"
                          align="start"
                          style={{
                            zIndex: config.dropdownMenuZIndex,
                          }}
                        >
                          <DropdownMenuItem
                            className="cursor-pointer"
                            onClick={() => {
                              collect(productCollectInfo);
                            }}
                          >
                            <ArrowBigDown></ArrowBigDown>
                            <span>采集</span>
                          </DropdownMenuItem>
                          <DropdownMenuItem
                            className="cursor-pointer"
                            onClick={() => {
                              collect(productCollectInfo, true);
                            }}
                          >
                            <ArrowBigDownDash></ArrowBigDownDash>
                            <span>重新采集</span>
                          </DropdownMenuItem>
                          <DropdownMenuItem
                            className="cursor-pointer text-destructive hover:!text-destructive/90"
                            onClick={() => {
                              deleteSkuInfo(productCollectInfo);
                            }}
                          >
                            <Trash2></Trash2>
                            <span>删除</span>
                          </DropdownMenuItem>
                        </DropdownMenuContent>
                      </DropdownMenu>
                    </SidebarMenuItem>
                  );
                })}
              </SidebarMenu>
            </SidebarContent>
          </Sidebar>
        </div>
      </div>
    </SidebarProvider>
  );
}
